package com.yunc.base.aspect;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.yunc.base.security.UserEntity;
import com.yunc.base.utils.IPUtils;
import com.yunc.base.utils.ServletUtils;
import com.yunc.modules.sys.entity.SysLog;
import com.yunc.modules.sys.service.ISysLogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * 系统日志，切面处理类
 */
@Aspect
@Component
public class LogAspect {

	@Qualifier("taskExecutor")
	@Autowired
	private ThreadPoolTaskExecutor taskExecutor;
	@Autowired
	private ISysLogService sysLogService;

	@Pointcut("@annotation(com.yunc.base.aspect.Log)")
	public void logPointCut() { 
		
	}
	
	@Before("logPointCut()")
	public void saveSysLog(JoinPoint joinPoint) {
		// 获取request
		HttpServletRequest request = ServletUtils.getRequest();
		// 用户信息
		Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		taskExecutor.execute(() -> {
			MethodSignature signature = (MethodSignature) joinPoint.getSignature();
			Method method = signature.getMethod();
			SysLog sysLog = new SysLog();
			Log baseLog = method.getAnnotation(Log.class);
			if(baseLog != null){
				// 注解上的描述
				sysLog.setOperation(baseLog.value());
			}
			// 请求的方法名
			String className = joinPoint.getTarget().getClass().getName();
			String methodName = signature.getName();
			sysLog.setMethod(className + "." + methodName + "()");
			// 请求的参数
			Object[] args = joinPoint.getArgs();
			if (args != null && args.length > 0) {
				String params = JSON.toJSONString(args[0]);
				sysLog.setParams(params);
			}
			// 设置IP地址
			sysLog.setIp(IPUtils.getIp(request));
			if (principal != null && principal instanceof UserDetails) {
				String userId = ((UserEntity) principal).getUserId();
				sysLog.setUserId(userId);
			}
			sysLog.setCreateTime(DateUtil.date());
			sysLogService.save(sysLog);
		});
		// 或使用
		// AsyncManager.me().execute(AsyncFactory.recordSysLog(sysLog));
	}
	
}
